package com.syx.migration.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.syx.migration.domain.*;
import com.syx.migration.mapper.*;
import com.syx.migration.mapper.old.OldUserMapper;
import com.syx.migration.service.MgnLinkIdService;
import com.syx.migration.service.UserModuleService;
import com.syx.migration.utils.*;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * @author Administrator
 * @date 2024/6/5 11:34
 * @description: TODO
 */
@RequiredArgsConstructor
@Service
public class UserModuleServiceImpl implements UserModuleService {

    private final SysDeptMapper deptMapper;
    private final SysUserMapper userMapper;
    private final SyxReaderMapper readerMapper;
    private final SyxReaderRulesMapper readerRulesMapper;
    private final SyxReaderCategoryMapper readerCategoryMapper;

    private final MgnLinkIdService mgnLinkIdService;

    private final OldUserMapper oldUserMapper;

    private static final String BELONG = "aafde3efa746480ab7652b3be493dfc0";


    /**
     * 同步部门数据
     */
    @Override
    @DSTransactional
    public void migrationDept() {
        // 获取所有学校信息
        Map<String, Long> firstDept = this.getFirstDept();
        String tbName = "sys_dept";
        List<MgnLinkId> mgnLinkIds = new ArrayList<>();
        List<SysDept> list = BeanMapUtils.mapListToBeanList(oldUserMapper.getDeptList(BELONG), SysDept.class);
        list.forEach(item ->{
            String newId = TimeIdWorker.createId(item.getCreateTime());
            mgnLinkIds.add(new MgnLinkId(newId, item.getOldId(), tbName));
            String tenantId = SchoolUtils.getTenantIdByBelong(item.getBelong());
            item.setTenantId(tenantId);
            Long parentId = firstDept.get(tenantId);
            item.setParentId(parentId);
            item.setAncestors("0," + parentId);
            item.setDeptId(Long.parseLong(newId));
            item.setType("1");
        });
        deptMapper.insertBatch(list);
        mgnLinkIdService.batchInsert(mgnLinkIds);
    }

    /**
     * 获取当前新系统中所有存在的部门
     */
    private Map<String, Long> getFirstDept(){
        List<SysDept> list = deptMapper.selectList(new LambdaQueryWrapper<SysDept>().eq(SysDept::getType,"1"));
        Map<String, Long> map = new HashMap<>();
        list.forEach(item -> map.put(item.getTenantId(), item.getDeptId()));
        return map;
    }

    /**
     * 同步读者类别和借阅规则
     */
    @DSTransactional
    @Override
    public void migrationReaderTypeRule() {
        String tbName = "syx_reader_category";
        // 获取老系统中所有角色
        List<Map<String, Object>> roles = oldUserMapper.getRoles(BELONG);
        List<SyxReaderCategory> readerCategories = BeanMapUtils.mapListToBeanList(roles, SyxReaderCategory.class);
        List<MgnLinkId> mgnLinkIds = new ArrayList<>();
        List<SyxReaderCategory> saveList = new ArrayList<>();
        readerCategories.forEach(item -> {
            String newId = TimeIdWorker.createId(item.getCreateTime());
            String oldId = item.getOldId();
            String tenantId = SchoolUtils.getTenantIdByBelong(item.getBelong());
            item.setTenantId(tenantId);
            item.setId(Long.valueOf(newId));
            // 存储对应借阅规则
            if (this.insertBorrowRule(item, newId, oldId)) {
                mgnLinkIds.add(new MgnLinkId(newId, item.getOldId(), tbName));
                // 获取本角色可用的馆藏
                item.setRoomIds(this.oldLibraryIdList2NewIdStr(MapUtils.singleMap2List(oldUserMapper.getRoomIdsByRoleId(oldId), String.class, "libraryId")));
                saveList.add(item);
            }
        });
        readerCategoryMapper.insertBatch(saveList);
        mgnLinkIdService.batchInsert(mgnLinkIds);
    }

    /**
     * 同步读者
     */
    @DSTransactional
    @Override
    public void migrationReader() {
        // old sex 0 - 男；1 - 女
        // new sex 0未知，1男，2女
        // 读者类别（角色）map
        Map<String, String> categoryMap = mgnLinkIdService.getMapByTbName("syx_reader_category");
        // 部门map
        Map<String, String> deptMap = mgnLinkIdService.getMapByTbName("sys_dept");
        List<SyxReader> syxReaders = BeanMapUtils.mapListToBeanList(oldUserMapper.getReaderList(BELONG), SyxReader.class);
        int size = syxReaders.size();
        int flag = size / 100;
        int i = 0;
        List<MgnLinkId> mgnLinkIds = new ArrayList<>();
        String tbName = "syx_reader";
        String defPassword = "$2a$10$GZ5kiZvW6sPqmvc.OohP6exupKzQLuU7vEMO/mLPIuljQMoLAL/ie";
        for (SyxReader item : syxReaders) {
            try {
                if (i % flag == 0){ // 每十分之一睡眠10-5ms
                    Thread.sleep(new Random().nextInt(5) + 5);
                }
                i++;
                String newId = TimeIdWorker.createId(item.getCreateTime());
                Long id = BaseUtils.str2Long(newId);
                item.setReaderId(id);
                String sex = item.getSex();
                if (StringUtils.isBlank(sex)){
                    sex = "0";
                }else{
                    sex = sex.equals("0") ? "1" : "2";
                }
                item.setSex(sex);
                item.setPassword(defPassword);
                item.setIdentity("0");
                item.setDeptId(BaseUtils.str2Long(deptMap.get(item.getOldDeptId())));
                item.setRuleId(BaseUtils.str2Long(categoryMap.get(item.getOldRtId())));
                item.setTenantId(SchoolUtils.getTenantIdByBelong(item.getBelong()));
                item.setCreateTime(item.getCreateTime());
                item.setFinishTime(BaseUtils.strDate2StrDateTime(item.getFinishTime()));
                mgnLinkIds.add(new MgnLinkId(newId, item.getOldId(), tbName));
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        mgnLinkIdService.batchInsert(mgnLinkIds);
        readerMapper.insertBatch(syxReaders);
    }

    /**
     * 补充不存在部门的读者信息
     */
    @DSTransactional
    @Override
    public void suppReaderDept() {
        // 老系统中数据异常的读者
        Map<String, String> schoolMap = mgnLinkIdService.getMapByTbName("syx_school");
        List<OldUserDept> readerList = oldUserMapper.getReaderListNoDepart();
        Map<String, List<OldUserDept>> belongColl = readerList.stream()
                .filter(item -> item.getBelong().equals("dff9762f7052434db0e3632e5a8b1c71")).collect(Collectors.groupingBy(OldUserDept::getBelong));
        for (String belong : belongColl.keySet()) {
            List<OldUserDept> readerDeptList = belongColl.get(belong);
            Map<String, List<OldUserDept>> deptColl = readerDeptList.stream().collect(Collectors.groupingBy(OldUserDept::getDepartName));
            String tenantId = schoolMap.get(belong);
            for (String deptName : deptColl.keySet()) {
                SysDept dept = deptMapper.selectOne(new LambdaQueryWrapper<SysDept>()
                        .eq(SysDept::getDeptName, deptName)
                        .eq(SysDept::getTenantId, tenantId)
                        .last("limit 1"));
                List<OldUserDept> readers = deptColl.get(deptName);
                List<String> oldReaderIds = readers.stream().map(OldUserDept::getId).toList();
                List<String> newReaderIds = mgnLinkIdService.getNewIdsByOldIds(oldReaderIds, "syx_reader");
                if (CollUtil.isNotEmpty(newReaderIds)){
                    System.out.println(tenantId);
                    System.out.println(newReaderIds);
                    List<SyxReader> syxReaderList = readerMapper.selectList(new LambdaQueryWrapper<SyxReader>()
                            .eq(SyxReader::getTenantId, tenantId)
                            .in(SyxReader::getReaderId, newReaderIds)
                            .isNull(SyxReader::getDeptId));
                    System.out.println(syxReaderList);
                    Long deptId = null;
                    // 创建部门
                    if (Objects.isNull(dept)){
                        SysDept parentDept = deptMapper.selectOne(new LambdaQueryWrapper<SysDept>()
                                .eq(SysDept::getDeptName, "读者部")
                                .eq(SysDept::getTenantId, tenantId)
                                .last("limit 1"));
                        SysDept saveDept = new SysDept();
                        saveDept.setParentId(parentDept.getDeptId());
                        saveDept.setAncestors(parentDept.getAncestors() + "," + parentDept.getDeptId());
                        saveDept.setDeptName(deptName);
                        saveDept.setTenantId(tenantId);
                        saveDept.setType("1");
                        int insert = deptMapper.insert(saveDept);
                        deptId = saveDept.getDeptId();
                    }else {
                        deptId = dept.getDeptId();
                    }
                    for (SyxReader item : syxReaderList) {
                        item.setDeptId(deptId);
                        readerMapper.updateById(item);
                    }
                }else {
                    continue;
                }
            }
        }
        // 获取新系统中不存在部门的读者列表
        // 查询新老系统读者对应关系表
        // 根据老系统中部门名称获取新系统中部门id，没有就新建一个，parentId为读者部
        // 更新读者部门id
    }

    /**
     * 去除重复借阅证号
     */
    @Override
    public void clearRepetitionBorrowCard(String tenantId) {
        List<RepetReaderVo> list = readerMapper.repetReaderList(tenantId);
        List<Long> removeIds = new ArrayList<>();
        list.forEach(item ->{
            String borrowCard = item.getBorrowCard();
            List<SyxReader> itemList = readerMapper.selectList(new LambdaQueryWrapper<SyxReader>()
                    .eq(SyxReader::getBorrowCard, borrowCard)
                    .orderByDesc(SyxReader::getScore));
            int size = itemList.size();
            for (int i = size - 1; i > 0 ; i--) {
                removeIds.add(itemList.get(i).getReaderId());
            }
        });
        readerMapper.deleteBatchIds(removeIds);
        System.out.println(removeIds.size());
        System.out.println(list.size());
    }

    /**
     * 存储借阅规则
     */
    private Boolean insertBorrowRule(SyxReaderCategory item, String newId, String oldId){
        SyxReaderRules bkReaderRules = null;
        SyxReaderRules jlReaderRules = null;

        // 获取图书借阅规则
        Map<String, Object> bkRuleMap = MapUtils.mapList2Map(oldUserMapper.getBorrowRoleOfBk(oldId));
        if (Objects.nonNull(bkRuleMap)){
            bkReaderRules = BeanMapUtils.mapToBean(bkRuleMap, SyxReaderRules.class);
        }

        // 获取期刊借阅规则
        Map<String, Object> jlRuleMap = MapUtils.mapList2Map(oldUserMapper.getBorrowRoleOfJournal(oldId));
        if (Objects.nonNull(jlRuleMap)){
            jlReaderRules = BeanMapUtils.mapToBean(jlRuleMap, SyxReaderRules.class);
        }

        // 如果两个都为空就跳过本角色
        if (Objects.isNull(bkReaderRules) && Objects.isNull(jlReaderRules)){
            return false;
        }

        boolean flagSame = false;

        String isSame = "0";

        if (Objects.nonNull(bkReaderRules)){
            flagSame = true;
        }else{
            bkReaderRules = BeanUtil.copyProperties(jlReaderRules, SyxReaderRules.class);
        }

        if (Objects.nonNull(jlReaderRules)){
            if (flagSame){
                isSame = "1";
            }
        }else{
            jlReaderRules = BeanUtil.copyProperties(bkReaderRules, SyxReaderRules.class);
        }

        bkReaderRules.setReaderCategoryId(Long.valueOf(newId));
        bkReaderRules.setId(Long.valueOf(TimeIdWorker.createId(bkReaderRules.getCreateTime())));
        bkReaderRules.setType("1");
        bkReaderRules.setTenantId(item.getTenantId());
        bkReaderRules.setCreateTime(item.getCreateTime());
        readerRulesMapper.insert(bkReaderRules);

        jlReaderRules.setReaderCategoryId(Long.valueOf(newId));
        jlReaderRules.setId(Long.valueOf(TimeIdWorker.createId(jlReaderRules.getCreateTime())));
        jlReaderRules.setType("2");
        jlReaderRules.setTenantId(item.getTenantId());
        jlReaderRules.setCreateTime(item.getCreateTime());
        readerRulesMapper.insert(jlReaderRules);

        item.setIsSame(isSame);

        return true;
    }

    /**
     * 老表藏书室id集合转换新表藏书室id字符串
     */
    private String oldLibraryIdList2NewIdStr(List<String> oldIds){
        // 从关联表中获取新表id集合
        List<String> libraryIds = mgnLinkIdService.getNewIdsByOldIds(oldIds, "syx_library_room");
        if (CollUtil.isEmpty(libraryIds)){
            return null;
        }
        return String.join(",", libraryIds);
    }



}
